package com.css.dzj.dzjportal.sys.user.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import com.css.aq.server.service.BaseService;
import com.css.dzj.dzjportal.common.annotation.SysLog;
import com.css.dzj.dzjportal.common.util.R;
import com.css.dzj.dzjportal.common.util.Restful.RestfulUtil;
import com.css.dzj.dzjportal.common.util.ServiceUtil;
import com.css.dzj.dzjportal.common.util.loginInfo.GetLoginInfo;
import com.css.dzj.dzjportal.common.validator.ValidatorUtils;
import com.css.dzj.dzjportal.sys.user.entity.LoginUser;
import com.css.dzj.dzjportal.sys.user.entity.User;
import com.css.dzj.dzjportal.sys.user.form.LoginForm;
import com.css.dzj.dzjportal.sys.user.service.UserService;
import com.css.dzj.dzjportal.sys.user.service.impl.UserServiceImpl;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.*;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 登录逻辑
 *
 * @author liangxg
 */
@RestController
@RequestMapping("/login")
@PropertySource(value = "classpath:base.properties")
public class LoginController {
    @Autowired
    UserServiceImpl userServiceImp;
    @Autowired
    HttpServletRequest request;
    @Autowired
    RestTemplate restTemplate;
    @Autowired
    private GetLoginInfo getLoginInfo;

    //HttpServletResponse response;

    @Autowired
    private RedisTemplate redisTemplate;
    @Value("${BASE_URL}")
    private String BASE_URL;
    @Value("${BASE_LOGIN_CONTROLLER}")
    private String BASE_LOGIN_CONTROLLER;
    @Autowired
    BaseService baseService;
    @Autowired
    private UserService userService;

    /* @SysLog("用户登录base")*/
    @PostMapping("/doLogin")
    synchronized public R  loginAP(@RequestBody LoginForm loginForm, HttpServletResponse response) throws IOException {

        // 若session中token不为空，则移除token
        HttpSession session = request.getSession();
        //获取用户信息
        String url = BASE_URL + "/platform/api/org/users/" + loginForm.getLoginName() + "/loginauth";
        Map<String, String> map = new HashMap<>();
        map.put("appCode", loginForm.getAppCode());
        map.put("cipher", loginForm.getPassword());
        HttpMethod method = HttpMethod.POST;
        Map body = RestfulUtil.sendRestful(request, map, url, method);

        //设置用户锁定信息
        String title = "再次访问";
        Integer visitCount = new Integer(0);
        String visitCountKey = new String("visitCount");
        String userIDKey = new String("userID");
        String userID = new String("youke");

        if (session.isNew()) {
            title = "访问";
            session.setAttribute(userIDKey, userID);
            session.setAttribute(visitCountKey, visitCount);
            if (session.getAttribute("token") != null) {
                session.removeAttribute("token");
            }
        }else{
            visitCount = (Integer) session.getAttribute(visitCountKey);
            if(visitCount ==null||(!StringUtils.isEmpty(session.getAttribute("isNew"))&&session.getAttribute("isNew").toString().equals("true"))){
                visitCount = 0;
            }
            visitCount += 1;
            //用户登陆成功后点击退出，重新登陆系统依次后，将成功登陆信息置为false
            session.setAttribute("isNew",false);
            userID = (String) session.getAttribute(userIDKey);
            session.setAttribute(visitCountKey, visitCount);
            if (session.getAttribute("token") != null) {
                session.removeAttribute("token");
            }
            if (visitCount >= 5) {
                //如果登陆次数大于2判断用户信息是否存在
                if(StringUtils.isEmpty((Map) body.get("data"))){
                    //调用platform接口锁定用户
                    //销毁session，清零;
                    session.invalidate();
                    return R.error("登陆次数超过5次，账号已锁定！");
                }else {
                    Map data = (Map) body.get("data");
                    if (StringUtils.isEmpty(data.get("userId"))) {
                        //调用platform接口锁定用户
                        //销毁session，清零;
                        session.invalidate();
                        return R.error("登陆次数超过5次，账号已锁定！");
                    }
                }
            }
        }
        if(StringUtils.isEmpty((Map) body.get("data"))){
            return R.error("用户不存在或密码错误");
        }
        Map data = (Map) body.get("data");
        if(StringUtils.isEmpty(data.get("userId"))){
            return R.error("用户不存在或密码错误");
        }
        String userId = data.get("userId").toString();
        if ((boolean) data.get("success")) {
            session.setAttribute("token", data.get("token").toString());
            session.setAttribute("userId", userId);
            session.setAttribute("userName", loginForm.getLoginName());
            session.setAttribute("password", loginForm.getPassword());
            //用来区分服务门户和工作门户
            session.setAttribute("portalType", "GZ");
            // 获取当前登录用户信息
            JSONObject userInfo = JSONObject.parseObject(JSON.toJSONString(getLoginInfo.getUserInfo(request)));
            LoginUser lu = JSON.parseObject(userInfo.toString(), LoginUser.class);
            session.setAttribute("_USER_LOGIN_INFO_", lu);

            // root的子组织机构
            JSONArray org = getLoginInfo.getOrgMenuChildren("root", request);
            System.out.println(org);
            // 获取字典测试
            JSONArray dic = (JSONArray)getLoginInfo.getDict("dzqs:auditModule", request).get("data");
            System.out.println(dic);

            ValueOperations<String, Object> vo = redisTemplate.opsForValue();
            String wt = JSON.toJSONString(vo.get("_USER_LOGIN_INFO_" + userId));
            if(!StringUtils.isEmpty(wt) || !"null".equals(wt)){
                redisTemplate.delete("_USER_LOGIN_INFO_" + userId);
            }
            //将用户信息存入redis中并设定redis存储一个小时
            vo.set("_USER_LOGIN_INFO_" + userId, userInfo, 60, TimeUnit.MINUTES);
 
            //将redis的key作为cookie的value存入其中
            Cookie cookie = new Cookie("userInfo", "_USER_LOGIN_INFO_" + userId);
            cookie.setPath("/");
            response.addCookie(cookie);
            //将session登陆次数清空，session添加isNew属性并将isNew设置成true
            session.setAttribute("isNew",true);
            return R.ok().put("data", userInfo);
        } else {
            return R.error("用户不存在或密码错误");
        }
    }

    /***
     * 登录验证
     * @param loginForm
     * @return
     */
    @SysLog("用户登录 withoutBase")
    @PostMapping("/checkUser")
    public R checkLogin(@RequestBody LoginForm loginForm) {
        try {
            //表单验证
            ValidatorUtils.validateEntity(loginForm);
            //获取登录用户名
            String userName = loginForm.getLoginName();
            //获取登录密码
            String password = DigestUtils.sha256Hex(loginForm.getPassword());
            User user = userServiceImp.findUserByNameAndPwd(userName, password);
            if (user == null || "".equals(user)) {
                return R.error(500, "用户不存在");
            } else {
                HttpSession session = request.getSession();
                session.setAttribute("userName", userName);
                Cookie cookie = new Cookie("userName", userName);
                cookie.setPath("/");
                //response.addCookie(cookie);
                return R.ok("登录成功！");
            }

        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }

    /**
     * 退出逻辑
     *
     * @param response
     * @return
     */
    @PostMapping("/logout")
    public R loginOut(HttpServletResponse response) {

        try {
            //获取session
            HttpSession session = request.getSession();
            LoginUser userInfo = (LoginUser) session.getAttribute("_USER_LOGIN_INFO_");
            String userId = userInfo.getUserId();
            //移除session
            session.removeAttribute("_USER_LOGIN_INFO_");
            //去除cookie
            Cookie cookie = new Cookie("userInfo", "");
            cookie.setPath("/");
            response.addCookie(cookie);
            //去除redis中的用户信息
            redisTemplate.delete("_USER_LOGIN_INFO_" + userId);
            //baseService.logSuccess(3, "退出登录", "2");
            return R.ok();
        }catch (Exception e){
            return R.error(e.getMessage());
        }
    }

}
